/**
 * File: sqlite.js.
 * Author: W A P.
 * Email: 610585613@qq.com.
 * Datetime: 2018/07/24.
 */
var fs = require('fs');
var sqlite3 = require('sqlite3').verbose();
//数据库对象
var DB = DB || {};
//是否允许建表标识
var createTableFlag = false;
//建表条件语句(记录推送消息)
var createTbWhereSQL =
    'id varchar(64) not null primary key , name varchar(64) , bizCode varchar(1024) UNIQUE , itemID varchar(1024) , createtime integer , message varchar(1024) , type varchar(16) , redircturl varchar(1024) , datetime integer , btype varchar(16) , status integer ';
//记录推送消息表名
var createTableName = 'message_log';
//配置文件名称
var configFile = 'app.config';

/**
 * @function sqliteDB实例化对象函数
 */
DB.SqliteDB = function(file) {
    try {
        //实例化数据库DB文件
        DB.db = new sqlite3.Database(file);

        //fs.writeFileSync(configFile, JSON.stringify({ createTableFlag: true }));

        //读取文件中的bizcode数据
        var data = fs.readFileSync(configFile, 'utf8'),
            data = JSON.parse(data);

        //获取配置文件标识
        createTableFlag = typeof data == 'undefined' || typeof data == 'null' ?
            createTableFlag :
            data['createTableFlag'];

        //数据库DB文件是否存在
        DB.exist = fs.existsSync(file);
        if (!DB.exist) {
            console.log('creating db file! ');
            fs.openSync(file, 'w');
        }
    } catch (error) {
        console.log(error);
    }
};

/**
 * @function 打印错误日志函数
 */
DB.printErrorInfo = function(err) {
    console.log('Error Message:' + err.message + ' ErrorNumber:' + err);
};

/**
 * @function 建表函数
 */
DB.SqliteDB.prototype.createTable = function(sql) {
    try {
        DB.db.run('BEGIN TRANSACTION;');
        DB.db.serialize(function() {
            DB.db.run(sql, function(err) {
                if (null != err) {
                    DB.printErrorInfo(err);
                    return;
                }
            });
        });
        DB.db.run('COMMIT TRANSACTION;');
    } catch (error) {
        console.log('create table error : ' + error);
        console.log('sql : ' + sql);
    }
};

/**
 * @function 插入数据函数
 */
DB.SqliteDB.prototype.insertData = function(sql, objects) {
    try {
        DB.db.run('BEGIN TRANSACTION');
        DB.db.serialize(function() {
            var stmt = DB.db.prepare(sql);
            for (var i = 0; i < objects.length; ++i) {
                stmt.run(objects[i]);
            }
            stmt.finalize();
        });
        DB.db.run('COMMIT TRANSACTION');
    } catch (error) {
        console.log('insert data error : ' + error);
        console.log('sql : ' + sql + ' objects : ' + JSON.stringify(objects));
    }
};

/**
 * @function 查询表数据函数
 */
DB.SqliteDB.prototype.queryData = function(sql, param, callback) {
    try {
        DB.db.all(sql, param, function(err, rows) {
            if (null != err) {
                DB.printErrorInfo(err);
                return;
            }
            //deal query data.
            if (callback) {
                callback(rows);
            }
        });
    } catch (error) {
        console.log('query data error : ' + error);
    }
};

/**
 * @function 查询表数据函数（一条）
 */
DB.SqliteDB.prototype.getData = function(sql, param, callback) {
    try {
        DB.db.get(sql, param, function(err, rows) {
            if (null != err) {
                DB.printErrorInfo(err);
                return;
            }
            // deal query data.
            if (callback) {
                callback(rows);
            }
        });
    } catch (error) {
        console.log('get data error : ' + error);
    }
};

/**
 * @function 执行SQL语句函数
 */
DB.SqliteDB.prototype.executeSql = function(sql) {
    try {
        DB.db.run(sql, function(err) {
            if (null != err) {
                DB.printErrorInfo(err);
            }
        });
    } catch (error) {
        console.log('execute sql error : ' + error);
    }
};

/**
 * @function 关闭数据库连接函数
 */
DB.SqliteDB.prototype.close = function() {
    try {
        DB.db.close();
    } catch (error) {
        console.log('close database error : ' + error);
    }
};

/**
 * @function 创建表单函数
 */
DB.SqliteDB.prototype.createNewTable = function(tableName, wherearg) {
    //全局变量 创建表单标识
    if (createTableFlag) {
        try {
            //建表语句
            create_tb_cmd =
                'create table if not exists ' + tableName + ' (  ' + wherearg + ' )';
            //执行建表语句
            this.createTable(create_tb_cmd);
            //设置建表状态
            createTableFlag = false;
        } catch (except) {
            console.log(
                'table {tableName} maybe exist , create table {tableName} fail '.replace(
                    '{tableName}',
                    tableName
                )
            );
            //设置建表状态
            createTableFlag = false;
        } finally {
            //读取文件中的bizcode数据
            var data = fs.readFileSync(configFile, 'utf8');
            //解析为JSON格式
            data = JSON.parse(data);
            //将改变后的createTableFlag写入data
            data.createTableFlag = createTableFlag;

            //获取datastr
            var datastr = JSON.stringify(data);

            //将config配置消息写入文件中
            fs.writeFileSync(configFile, datastr);

            console.log('write confige info to filesystem . ');
            console.log('data : ' + data + ' data string :' + datastr);
        }
    }
};

/**
 * @function 插入表单函数
 */
DB.SqliteDB.prototype.insertNewTable = function(
    tableName,
    wherearg,
    valuearg,
    swherearg,
    svaluearg
) {
    //将本函数对象转存为that，以便在回调函数中使用
    let that = this;

    //进行建表语句
    this.createNewTable(tableName, createTbWhereSQL);

    try {
        //没有数据则插入数据
        this.selectNewTable(tableName, swherearg, svaluearg, function(flag) {
            if (!flag) {
                let valuestr = JSON.stringify(valuearg);
                //插入数据
                that.insertData(
                    'insert into ' + tableName + ' values( ' + wherearg + ' )', [valuearg]
                );
                console.log(
                    ' insert into ' + tableName + ' values ( ' + valuestr + ')'
                );
            }
        });
    } catch (error) {
        console.log('insert sql error: ' + error);
        console.log(
            'tableName : ' +
            tableName +
            ' wherearg : ' +
            wherearg +
            ' valuearg : ' +
            valuearg +
            ' swherearg : ' +
            swherearg +
            ' svaluearg : ' +
            svaluearg
        );
    }
};

/**
 * @function 查询表单函数（一条记录）
 */
DB.SqliteDB.prototype.selectNewTable = function(
    tableName,
    wherearg,
    valuearg,
    callback
) {
    //将本函数对象转存为that，以便在回调函数中使用
    let that = this;

    //查询结果集
    var rows;
    //进行建表语句
    this.createNewTable(tableName, createTbWhereSQL);

    try {
        this.getData(
            ' select * from ' + tableName + ' where ' + wherearg,
            valuearg,
            function(data) {
                rows = data;
                if (typeof rows != 'undefined') {
                    callback(true, rows);
                    return true;
                } else {
                    callback(false);
                    return false;
                }
            }
        );
    } catch (error) {
        console.log('select sql error: ' + error);
        console.log(
            'tableName : ' +
            tableName +
            ' wherearg : ' +
            wherearg +
            ' valuearg : ' +
            valuearg
        );
    }
};

/**
 * @function 查询表单函数(所有记录)
 */
DB.SqliteDB.prototype.selectNewTableAll = function(
    tableName,
    wherearg,
    valuearg,
    callback
) {
    //将本函数对象转存为that，以便在回调函数中使用
    let that = this;

    //查询结果集
    var rows;

    //进行建表语句
    this.createNewTable(tableName, createTbWhereSQL);

    try {
        this.queryData(
            ' select * from ' + tableName + ' where ' + wherearg,
            valuearg,
            function(data) {
                rows = data;
                if (typeof rows != 'undefined') {
                    callback(true, rows);
                    return true;
                } else {
                    callback(false);
                    return false;
                }
            }
        );
    } catch (error) {
        console.log('select sql error: ' + error);
        console.log(
            'tableName : ' +
            tableName +
            ' wherearg : ' +
            wherearg +
            ' valuearg : ' +
            valuearg
        );
    }
};

//export SqliteDB.
exports.SqliteDB = DB.SqliteDB;